package com.dingding.service.core.common.dao.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.daox.IBaseDaoX;
import com.dingding.common.core.base.daox.ICriteriaBaseDao;
import com.dingding.common.core.base.daox.ISQLBaseDao;
import com.dingding.common.core.beans.special.SpecialOrderdesignateset;
import com.dingding.common.core.beans.special.SpecialUserAuthInfo;
import com.dingding.common.core.beans.special.SpecialUserloginrecord;
import com.dingding.common.core.beans.special.Specialuseraccount;
import com.dingding.common.core.beans.special.Specialuserinfo;
import com.dingding.common.core.beans.special.Specialuserlogin;
import com.dingding.common.core.beans.special.Specialuserposition;
import com.dingding.common.core.beans.special.Specialuservehicleinfo;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.facade.user.common.constans.special.UserInfoConstant;
import com.dingding.facade.user.common.dto.common.ReqRegisterDriverDTO;
import com.dingding.facade.user.common.enums.AppointOrderType;
import com.dingding.facade.user.common.enums.DepositSet;
import com.dingding.facade.user.common.enums.OutwardRunStatus;
import com.dingding.facade.user.common.enums.UserAccountStatus;
import com.dingding.facade.user.common.enums.UserRole;
import com.dingding.facade.user.common.enums.UserSex;
import com.dingding.facade.user.common.enums.UserStatus;
import com.dingding.facade.user.common.enums.VoiceAnnouncements;
import com.dingding.facade.user.dto.common.driver.ReqSyncDriverAuthStateDTO;
import com.dingding.facade.user.dto.common.driver.ResDriverAuthDetailsDTO;
import com.dingding.facade.user.dto.common.driver.ResSyncDriverAuthStateDTO;
import com.dingding.service.core.common.dao.IDriverDao;
import com.dingding.service.core.common.sql.DriverSQL;
import com.dingding.service.user.auth.sql.DriverUserSQL;
import com.dingding.service.user.auth.sql.SyncDriverAuthStateSQL;

/**
 * 
 * @ClassName: DriverDaoImpl
 * @Description: 司机共同dao操作共同实现类
 * @author hufan
 * @date 2016年12月1日 下午7:55:27
 *
 */
@Component("driverDao")
public class DriverDaoImpl implements IDriverDao {

	Logger log = Logger.getLogger(DriverDaoImpl.class);

	@Resource(name = "SQLBaseDao")
	private ISQLBaseDao sqlBaseDao;

	@Resource(name = "criteriaBaseDao")
	private ICriteriaBaseDao criteriaBaseDao;

	@Resource(name = "baseDaoX")
	private IBaseDaoX baseDaoX;
	
	/**
	 * 
	 * @Title: saveSpecialuservehicleinfo 
	 * @Description: 保存司机车辆信息
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean saveSpecialuservehicleinfo(Specialuservehicleinfo specialuservehicleinfo) {
		return criteriaBaseDao.save(specialuservehicleinfo);
	}
	
	
	/**
	 * 
	 * @Title: saveSpecialUserAuthInfo 
	 * @Description: 添加用户认证信息
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean saveSpecialUserAuthInfo(SpecialUserAuthInfo specialUserAuthInfo) {
		return criteriaBaseDao.save(specialUserAuthInfo);
	}


	/**
	 * 
	 * @Title: saveSpecialuserinfo 
	 * @Description: 保存司机基本信息
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	public boolean saveSpecialuserinfo(Specialuserinfo specialuserinfo) {
		return criteriaBaseDao.save(specialuserinfo);
	}

	/**
	 * 
	 * @Title: getSpecialuservehicleinfoByUserId 
	 * @Description: 根据userid查询车辆信息表
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public Specialuservehicleinfo getSpecialuservehicleinfoByUserId(String userId) {
		Criterion criterion = Restrictions.eq("userId", userId);

		try {
			return criteriaBaseDao.queryCriteriaListUnique(Specialuservehicleinfo.class, criterion);
		} catch (Exception e) {

			log.error("根据用户Id获取司机车辆信息时出现异常   类：" + this.getClass() + " getSpecialuservehicleinfoByUserId() ;userId: "+userId, e);
		}
		return null;
	}

	/**
	 * 
	 * @Title: updateSpecialuservehicleinfo 
	 * @Description: 更新司机车辆信息
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean updateSpecialuservehicleinfo(Specialuservehicleinfo specialuservehicleinfo) {
		return criteriaBaseDao.update(specialuservehicleinfo);
	}


	/**
	 * 
	 * @Title: getSpecialuserinfoByUserId 
	 * @Description: 根据userid查询司机信息
	 * @param  参数说明  userid
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public Specialuserinfo getSpecialuserinfoByUserId(String userId) {
		
		Criterion criterion = Restrictions.eq("userId", userId);

		try {
			return criteriaBaseDao.queryCriteriaListUnique(Specialuserinfo.class, criterion);
		} catch (Exception e) {

			log.error("根据用户Id获取司机车辆信息时出现异常   类：" + this.getClass() + " getSpecialuserinfoByUserId() ;userId: "+userId, e);
			
		}
		return null;
	}

	/**
	 * 
	 * @Title: getSpecialuservehicleinfoByLisencePlate 
	 * @Description: 根据userid、车牌号码查询车辆信息表
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public Specialuservehicleinfo getSpecialuservehicleinfoByLisencePlate(String lisencePlate) {

		Criterion criterion = Restrictions.eq("lisencePlate", lisencePlate);

		try {
			return criteriaBaseDao.queryCriteriaListUnique(Specialuservehicleinfo.class, criterion);
		} catch (Exception e) {

			log.error("根据车牌号码获取司机车辆信息时出现异常   类：" + this.getClass() + " getSpecialuservehicleinfoByLisencePlate() ;lisencePlate: "+lisencePlate, e);
		}
		return null;
	}

	/**
	 * 
	 * @Title: updateSpecialuserinfo 
	 * @Description: 更新Specialuserinfo
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean updateSpecialuserinfo(Specialuserinfo specialuserinfo) {
		return criteriaBaseDao.update(specialuserinfo);
	}

	/**
	 * 
	 * @Title: getSpecialUserAuthInfo 
	 * @Description: 根据userId查询用户身份信息
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public SpecialUserAuthInfo getSpecialUserAuthInfo(String userId) {
		Criterion criterion = Restrictions.eq("specialUserId", userId);

		try {
			return criteriaBaseDao.queryCriteriaListUnique(SpecialUserAuthInfo.class, criterion);
		} catch (Exception e) {

			log.error("根据车牌号码获取司机车辆信息时出现异常   类：" + this.getClass() + " getSpecialUserAuthInfo() ;userId: " + userId, e);
		}
		return null;
	}

	/**
	 * 
	 * @Title: updateSpecialUserAuthInfo 
	 * @Description: 修改司机认证信息
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean updateSpecialUserAuthInfo(SpecialUserAuthInfo specialUserAuthInfo) {
		return criteriaBaseDao.update(specialUserAuthInfo);
	}

	/**
	 * 
	 * @Title: getResDriverAuthDetails 
	 * @Description: 根据用户id查询司机认证详情(包含司机信息、车辆信息)
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public ResDriverAuthDetailsDTO getResDriverAuthDetails(String userId) {
		
		ResDriverAuthDetailsDTO resDriverAuthDetailsDTO = null;
		try {
			resDriverAuthDetailsDTO = sqlBaseDao.sqlToCustomBeanUnique(ResDriverAuthDetailsDTO.class, DriverUserSQL.DRIVER_INFO_DETAILS, userId);
		} catch (Exception e) {
			
			log.error("根据车牌号码获取司机车辆信息时出现异常   类：" + this.getClass() + " getResDriverAuthDetails() ;userId: "+userId, e);
		}
		return resDriverAuthDetailsDTO;
	}

	/**
	 * 
	 * @Title: changeDriverRole 
	 * @Description: 修改用户登录表中的用户角色
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean changeDriverRole(String userId, Integer userRole) {
		
		Specialuserlogin specialuserlogin = criteriaBaseDao.getById(userId, Specialuserlogin.class);
		if(specialuserlogin == null){
			return false;
		}else{
			specialuserlogin.setUserRole(userRole);
		}
		return true;
	}

	/**
	 * 
	 * @Title: registerDriver 
	 * @Description: 注册司机(专车司机或出租车司机)
	 * @author YHQ 
	 * @since V2.5.7
	 * @return boolean    返回类型
	 * 
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean registerDriver(String uuid,ReqRegisterDriverDTO registerDriverDTO) {
		
		try {

			Specialuserlogin specialuserlogin = createSpecialUserLogin(uuid, registerDriverDTO);
			Specialuserinfo specialuserinfo = createSpecialuserinfo(uuid, registerDriverDTO.getUserName());
			Specialuserposition specialuserposition = createSpecialuserposition(uuid,null);
			SpecialOrderdesignateset specialOrderdesignateset = createOrderdesignateset(uuid);
			Specialuseraccount specialuseraccount = createSpecialUserAccount(uuid);
			SpecialUserloginrecord specialUserloginrecord = createSpecialUserLoginRecord(uuid);

			// 用户登录
			baseDaoX.save(specialuserlogin);
			// 用户详细信息
			baseDaoX.save(specialuserinfo);
			// 用户位置记录
			baseDaoX.save(specialuserposition);
			// 专车用户指单设置
			baseDaoX.save(specialOrderdesignateset);
			// 专车用户账户
			baseDaoX.save(specialuseraccount);
			// 专车用户登录记录表
			baseDaoX.save(specialUserloginrecord);

			return true;

		} catch (Exception e) {
			log.error("注册司机，添加所有用户信息到DB中出现异常！", e);
		}
		
		return false;
	}
	
	/**
	 * 
	 * 创建用户登录信息保存bean
	 * 
	 * @Title: createSpecialUserLogin 
	 * @param specialUserLoginDTO
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	private Specialuserlogin createSpecialUserLogin(String userId, ReqRegisterDriverDTO registerDriverDTO) {

		Specialuserlogin specialuserlogin = new Specialuserlogin();

		specialuserlogin.setSuid(userId); // 主键ID
		specialuserlogin.setAliasId(ToolUtil.getUid()); // 用户ID
		specialuserlogin.setUserName(registerDriverDTO.getUserName()); // 手机号
		specialuserlogin.setUserStatus(UserStatus.login.getValue()); // 用户状态
		specialuserlogin.setUserRole(UserRole.nodriver.getValue()); // 用户角色
		specialuserlogin.setIsDeposit(DepositSet.no.getValue()); // 是否设置过提现密码
//		specialuserlogin.setClientType(specialUserLoginDTO.getClientType()); // 客户端类型
//		specialuserlogin.setLoginCity(specialUserLoginDTO.getLoginCity());// 登录城市
//		specialuserlogin.setClientVersion(specialUserLoginDTO.getAppVersion()); // app版本号
//		specialuserlogin.setImei(specialUserLoginDTO.getImei());// 手机设备出厂标识
		specialuserlogin.setLastLoginTime(new Date());
		specialuserlogin.setCreateTime(new Date());
		specialuserlogin.setDepositNumber(0); // 当日提现次数

		return specialuserlogin;

	}

	/**
	 * 
	 * 创建用户详细信息
	 * 
	 * @Title: createSpecialuserinfo 
	 * @param userId 用户ID 
	 * @param telPhone 手机号
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	private Specialuserinfo createSpecialuserinfo(String userId, String telPhone) {

		Specialuserinfo specialuserinfo = new Specialuserinfo();
		specialuserinfo.setSuId(UUID.randomUUID().toString()); // 主键ID
		specialuserinfo.setUserId(userId); // 用户ID
		specialuserinfo.setNickName(UserInfoConstant.DEFAULT_USER_NICKNAME); // 用户昵称
		specialuserinfo.setAge(0); // 年龄
		specialuserinfo.setSex(UserSex.noset.getValue()); // 性别
		specialuserinfo.setUserTabloidAvatar(UserInfoConstant.DEFAULT_TABLOID_USERAVATAR); // 用户缩略头像
		specialuserinfo.setUserAvatar(UserInfoConstant.DEFAULT_USERAVATAR);// 用户头像
		specialuserinfo.setTelPhone(telPhone); // 手机号
		specialuserinfo.setUserLevel(new BigDecimal(5)); // 级

		return specialuserinfo;

	}

	/**
	 *
	 * 创建用户位置初始化数据
	 * @Title: createSpecialuserposition 
	 * @param uesreId 用户ID
	 * @param currentCity 城市
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	private Specialuserposition createSpecialuserposition(String userId, String currentCity) {

		Specialuserposition specialuserposition = new Specialuserposition();
		specialuserposition.setSupId(UUID.randomUUID().toString()); // 主键ID
		specialuserposition.setUserId(userId); // 用户ID
		specialuserposition.setCurrentCity(currentCity); // 当前城市
		specialuserposition.setLongitude(0d); // 经度
		specialuserposition.setLatitude(0d);// 纬度
		specialuserposition.setSupStatus(OutwardRunStatus.close.getValue()); // 状态
		specialuserposition.setOutwardRunTime(new Date()); // 出车时间
		specialuserposition.setOnlineDuration(new BigDecimal(0)); // 当日在线时长

		return specialuserposition;

	}

	/**
	 * 
	 * 创建用户指单初始化数据
	 * 
	 * @Title: createOrderdesignateset 
	 * @param userId 用户ID
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	private SpecialOrderdesignateset createOrderdesignateset(String userId) {

		SpecialOrderdesignateset specialOrderdesignateset = new SpecialOrderdesignateset();
		specialOrderdesignateset.setOdsId(UUID.randomUUID().toString()); // 主键ID
		specialOrderdesignateset.setUserId(userId);// 用户ID
		specialOrderdesignateset.setAppointOrderType(AppointOrderType.All.getValue()); // 指派类型
		specialOrderdesignateset.setVoiceAnnouncements(VoiceAnnouncements.Yes.getValue()); // 语音播报
		specialOrderdesignateset.setDistanceFilter(new BigDecimal(5)); // 距离筛选，默认5公里
		specialOrderdesignateset.setSetTime(new Date()); // 设置时间

		return specialOrderdesignateset;

	}

	/**
	 * 
	 * 创建专车用户账户初始化数据
	 * 
	 * @Title: createSpecialUserAccount 
	 * @param userId 用户ID
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	private Specialuseraccount createSpecialUserAccount(String userId) {

		Specialuseraccount specialuseraccount = new Specialuseraccount();
		specialuseraccount.setUaId(UUID.randomUUID().toString()); // 用户ID
		specialuseraccount.setUserId(userId); // 用户ID
		specialuseraccount.setCurrencyAmount(new BigDecimal(0)); // 余额
		specialuseraccount.setSysFreezeCashAmount(new BigDecimal(0)); // 系统冻结金额
		specialuseraccount.setFreezeCashAmount(new BigDecimal(0)); // 提现冻结金额
		specialuseraccount.setAccountStatus(UserAccountStatus.regular.getValue());
		return specialuseraccount;

	}

	/**
	 * 
	 * 保存用户登录记录信息
	 * 
	 * @Title: saveUserLoginRecord 
	 * @param userId 用户ID
	 * @param type 操作类型  登录 or 退出
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	public SpecialUserloginrecord createSpecialUserLoginRecord(String userId) {

		SpecialUserloginrecord specialUserloginrecord = new SpecialUserloginrecord();
		specialUserloginrecord.setUlrId(ToolUtil.getUid()); // 主键ID
		specialUserloginrecord.setUserId(userId); // 用户ID
		specialUserloginrecord.setCreateTime(new Date()); // 创建时间
		specialUserloginrecord.setType(UserStatus.login.getValue()); // 操作类型 登录 or 退出
		
		try {
			criteriaBaseDao.save(specialUserloginrecord);
		} catch (Exception e) {
			log.error("保存用户登录记录信息出现异常！", e);
		}

		return specialUserloginrecord;
	}


	/**
	 * 
	 * @Title: getSpecialUserVehicleInfo 
	 * @Description: 根据用户Id获取司机认证信息
	 * @param userId 用户Id
	 * @author YHQ 
	 * @since V2.5.7
	 * @return Specialuservehicleinfo    返回类型
	 * 
	 */
	@Override
	@Transactional(readOnly = true)
	public Specialuservehicleinfo getSpecialUserVehicleInfo(String userId) {
		
		try {
			return sqlBaseDao.sqlToCustomBeanUnique(Specialuservehicleinfo.class, DriverSQL.GET_SPECIAL_USER_VEHICLE_INFO_BY_USER_ID, userId);
		} catch (Exception e) {
			log.error("根据用户Id获取司机认证信息时出现异常   类：" + this.getClass() + " getSpecialUserVehicleInfo()", e);
		}
		
		return null;
	}
	
	/**
	 * 
	 * @Title: getResSyncDriverAuthState 
	 * @Description: 获取车主认证状态
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public ResSyncDriverAuthStateDTO getResSyncDriverAuthState(ReqSyncDriverAuthStateDTO reqSyncDriverAuthStateDTO) {
		try {
			// 根据用户Id获取该用户车主信息
			List<ResSyncDriverAuthStateDTO> resSyncDriverAuthStateDTOS = sqlBaseDao.listSqlToCustomBean(ResSyncDriverAuthStateDTO.class, SyncDriverAuthStateSQL.SYNC_DRIVER_AUTH_STATE, reqSyncDriverAuthStateDTO.getUserId());
		
			if(resSyncDriverAuthStateDTOS != null && resSyncDriverAuthStateDTOS.size() > 0){
				
				ResSyncDriverAuthStateDTO resSyncDriverAuthStateDTO = resSyncDriverAuthStateDTOS.get(0);
				
				return resSyncDriverAuthStateDTO;
			}else {
				//司机未提交过认证信息
				ResSyncDriverAuthStateDTO resSyncDriverAuthStateDTO = new ResSyncDriverAuthStateDTO();
				resSyncDriverAuthStateDTO.setAuthType(1);
				resSyncDriverAuthStateDTO.setSuvStatus(0);
				
				return resSyncDriverAuthStateDTO;
			}
			
		} catch (Exception e) {
			log.error("同步车主认证状态时出现异常   类：" + this.getClass() + " getResSyncDriverAuthState()", e);
		}
		
		return null;
	}
}
